package com.zhoug.zmui3.autocomplete;

import android.content.Context;
import android.graphics.Rect;
import android.text.Editable;
import android.text.InputFilter;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListAdapter;

import com.zhoug.common3.filters.BlankFilter;
import com.zhoug.common3.filters.CNToENCommaInputFilter;
import com.zhoug.common3.utils.CollectionUtils;
import com.zhoug.common3.utils.LogUtils;
import com.zhoug.common3.utils.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import androidx.appcompat.widget.AppCompatMultiAutoCompleteTextView;

/**
 * 自动补全输入框 支持多选
 * @Author: zhoug
 * @Date: 2023-11-01
 * @Description:
 */
public class ZMUIMultiAutoCompleteTextView extends AppCompatMultiAutoCompleteTextView {
    private static final String TAG = ">>>MyMultiAutoCompleteText";
    private static boolean DEBUG = true;

    /**
     * 获得焦点并且没有任何输入时是否显示默认数据窗口
     */
    protected boolean hasFocusShowDefaultData = true;
    /**
     * 单击列表项监听
     */
    protected OnItemClickListener mOnItemClickListener;
    /**
     * 点击列表是否关闭窗口
     */
    protected boolean mDropDownDismissedOnClickItem = false;
    /**
     * 是否可以关闭
     */
    protected boolean canClose = true;

    public ZMUIMultiAutoCompleteTextView(Context context) {
        super(context);
        init();
    }

    public ZMUIMultiAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ZMUIMultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setThreshold(1);
        setTokenizer(new CommaTokenizer());
        super.setOnItemClickListener(new AdapterViewOnItemClickListener());
        setFilters(new InputFilter[]{new CNToENCommaInputFilter(), new BlankFilter()});
        addTextChangedListener(new TextWatcher() {
            private int beforeSelectionIndex = 0;
            private String mBeforeText;

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                canClose = true;
                beforeSelectionIndex = getSelectionStart();
                mBeforeText = s != null ? s.toString() : null;
                if (DEBUG) {
                    LogUtils.d(TAG, "beforeTextChanged:mBeforeText=" + mBeforeText);
                    LogUtils.d(TAG, "beforeTextChanged:beforeSelectionIndex=" + beforeSelectionIndex);
                }
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (s != null) {
                    String input = s.toString();
                    if (DEBUG) {
                        LogUtils.d(TAG, "afterTextChanged:" + s);
                    }
                    ListAdapter adapter = getAdapter();
                    if (adapter instanceof ZMUIAutoCompleteAdapter) {
                        ((ZMUIAutoCompleteAdapter<?>) adapter).setInputText(input);
                    }
                    //判断是否需要去重
                    if (StringUtils.isNullOrEmpty(mBeforeText) || Objects.equals(mBeforeText, input) || StringUtils.countString(input, ",") < 2) {
                        if (DEBUG) {
                            LogUtils.d(TAG, "afterTextChanged:无需去重");
                        }
                        return;
                    }
                    boolean endWithComma = true;
                    //以逗号结尾的全部数据去重
                    if (!input.endsWith(",")) {
                        endWithComma = false;
                        //不是以逗号结尾的,最后一端文字不去重,可能还没输入完
                        input = input.substring(0, input.lastIndexOf(","));
                    }
                    //去重
                    String[] split = input.split(",");
                    if (split.length > 0) {
                        //List可以重复
                        List<String> temp = CollectionUtils.delRepeat(Arrays.asList(split));
                        int size = temp.size();
                        //有重复
                        if (!temp.isEmpty() && size != split.length) {
                            if (DEBUG) {
                                LogUtils.d(TAG, "afterTextChanged:有重复数据");
                            }
                            StringBuilder stringBuilder = new StringBuilder();
                            for (int i = 0; i < size; i++) {
                                stringBuilder.append(temp.get(i));
                                if (i < size - 1) {
                                    stringBuilder.append(",");
                                }
                            }
                            String result = stringBuilder.toString();
                            if (endWithComma && !result.isEmpty()) {
                                result = result + ",";
                            }
                            setText(result, false);
                            setSelection(Math.min(beforeSelectionIndex, result.length()));
                        }
                    }


                }
            }
        });


    }

    /**
     * 获得焦点并且没有任何输入时是否显示默认数据窗口
     * @param hasFocusShowDefaultData
     */
    public void setHasFocusShowDefaultData(boolean hasFocusShowDefaultData) {
        this.hasFocusShowDefaultData = hasFocusShowDefaultData;
    }

    @Override
    public boolean enoughToFilter() {
        if (hasFocusShowDefaultData) {
            super.enoughToFilter();
            return true;
        } else {
            return super.enoughToFilter();
        }
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        canClose = true;
        if (hasFocusShowDefaultData && focused) {
            Editable text = getText();
            if (text != null && text.toString().length() == 0) {
                ListAdapter adapter = getAdapter();
                if (adapter instanceof Filterable) {
                    Filter filter = ((Filterable) adapter).getFilter();
                    filter.filter("");
                }
            }
        }
    }

    @Override
    public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
        super.setAdapter(adapter);
        if (adapter instanceof ZMUIAutoCompleteAdapter) {
            ((ZMUIAutoCompleteAdapter<?>) adapter).setMultiSelect(true);
        }
        /*if(adapter!=null){
            adapter.registerDataSetObserver(new DataSetObserver() {

                @Override
                public void onChanged() {
                    super.onChanged();
                    int count = adapter.getCount();
                    if(count==0){
                        canClose=true;
                    }
                }

                @Override
                public void onInvalidated() {
                    super.onInvalidated();
                    int count = adapter.getCount();
                    if(count==0){
                        canClose=true;
                    }
                }
            });
        }*/
    }

    @Deprecated
    @Override
    public void setOnItemClickListener(AdapterView.OnItemClickListener l) {
        super.setOnItemClickListener(l);
    }

    //单击item监听
    private class AdapterViewOnItemClickListener implements AdapterView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            canClose = false;
            ListAdapter adapter = getAdapter();
            Object select = null;
            if (adapter != null) {
                select = adapter.getItem(position);
            }

            if (mOnItemClickListener != null) {
                mOnItemClickListener.onItemClick(parent, view, position, id, select);
            }
        }
    }

    /**
     * 单击列表项监听
     * @param onItemClickListener
     */
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.mOnItemClickListener = onItemClickListener;
    }



    @Override
    public void showDropDown() {
        super.showDropDown();
    }


    @Override
    public void dismissDropDown() {
        if (mDropDownDismissedOnClickItem || canClose) {
            super.dismissDropDown();
        }
    }


    @Override
    protected void onDetachedFromWindow() {
        canClose = true;
        super.onDetachedFromWindow();
    }

    @Override
    protected void onDisplayHint(int hint) {
        canClose = true;
        super.onDisplayHint(hint);
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        canClose = true;
        super.onWindowFocusChanged(hasWindowFocus);
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        canClose = true;
        return super.onKeyPreIme(keyCode, event);
    }


    /**
     * 多个数据逗号分割
     * @Author: zhoug
     * @Date: 2023-11-02
     * @Description:
     */
    public static class CommaTokenizer implements Tokenizer {
        // 用于查找当前光标位置之前的分隔符的位置并返回，向前查询
        // text - 用户已经输入的文本内容
        // cursor - 当前光标的位置，在文本内容后面
        @Override
        public int findTokenStart(CharSequence text, int cursor) {
            int i = cursor;

            while (i > 0 && text.charAt(i - 1) != ',') {
                i--;
            }
       /* while (i < cursor && text.charAt(i) == ' ') {
            i++;
        }*/

            return i;
        }

        // 用于查找当前光标位置之后的分隔符的位置并返回，向后查询
        // text - 用户已经输入的文本内容
        // cursor - 当前光标的位置，在文本内容之间
        @Override
        public int findTokenEnd(CharSequence text, int cursor) {
            int i = cursor;
            int len = text.length();

            while (i < len) {
                if (text.charAt(i) == ',') {
                    return i;
                } else {
                    i++;
                }
            }

            return len;
        }

        // 用于返回提示信息加上分隔符后的文本内容
        // text - 提示信息中的文本内容
        @Override
        public CharSequence terminateToken(CharSequence text) {
            int i = text.length();

       /* while (i > 0 && text.charAt(i - 1) == ' ') {
            i--;
        }*/

            if (i > 0 && text.charAt(i - 1) == ',') {
                return text;
            } else {
                if (text instanceof Spanned) {
                    SpannableString sp = new SpannableString(text + ",");
                    TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
                            Object.class, sp, 0);
                    return sp;
                } else {
                    return text + ",";
                }
            }
        }
    }

}
